import json
import os
import logging
import time
import traceback

import demjson
from flask import Blueprint, request, g, make_response, send_from_directory

from flask_restful import Resource, Api, reqparse, marshal, fields, current_app
from sqlalchemy import or_, and_, not_
from werkzeug.utils import secure_filename

from common.models import rds, db, cache
from common.models.course import Course, CourseTag, CourseType, Chapters, Sections, Tag
from common.models.user import UserBase
from common.utils.custom_output_json import custom_output_json
from common.model_fields.course import course_type, course_fields, chapters_fields, tag_fields, search_course_fields
from common.utils.login_util import login_required
from common.utils.utils import get_upload_token
from common.es.es import ES


UPLOAD_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'images')

course_bp = Blueprint('course_bp', __name__, url_prefix='/course')
api = Api(course_bp)


@api.representation('application/json')
def output_json(data, code=200, headers=None):
    return custom_output_json(data, code, headers)


class AddCourseType(Resource):
    """
    添加课程类别
    1、强制登录
    2、是否有添加的权限（默认超级管理员可以添加）
    3、前端获取课程类型参数
    4、校验参数（课程名称是否符合要求、是否已有当前课程）
    5、添加进去
    """

    @login_required
    def post(self):
        try:
            user_id = g.user_id
            user = UserBase.query.get(user_id)
            # 是否有添加的权限（默认超级管理员可以添加）
            if user.is_superuser != 2:
                msg = 'Not permission!'
                logging.error('AddCourseType is error:{}'.format(msg))
                return {'message': msg, 'code': 500}
            parser = reqparse.RequestParser()
            parser.add_argument('title')
            parser.add_argument('sequence', type=int)
            args = parser.parse_args()
            title = args.get('title')
            sequence = args.get('sequence')
            # 课程名称是否符合要求
            if len(title) > 16:
                msg = 'Title is too large!'
                logging.error('AddCourseType is error:{}'.format(msg))
                return {'message': msg, 'code': 500}
            # 是否已有当前课程
            num = CourseType.query.filter_by(title=title).count()
            if num >= 1:
                msg = 'This type is exist!'
                logging.error('AddCourseType is error:{}'.format(msg))
                return {'message': msg, 'code': 500}
            course = CourseType(title=title, sequence=sequence)
            db.session.add(course)
            db.session.commit()
            return marshal(course, course_type)
        except:
            error = traceback.format_exc()
            logging.error('AddCourseType is error:{}'.format(error))
            return {'message': 'AddCourseType error', 'code': 500}


class AddCourse(Resource):
    """
    添加课程
    """

    @login_required
    def post(self):
        try:
            user_id = g.user_id
            user = UserBase.query.get(user_id)
            # 是否有添加的权限（默认超级管理员可以添加）
            if user.is_superuser != 2:
                msg = 'Not permission!'
                logging.error('AddCourseType is error:{}'.format(msg))
                return {'message': msg, 'code': 500}
            parser = reqparse.RequestParser()
            parser.add_argument('title')
            parser.add_argument('desc')
            parser.add_argument('img_path')
            parser.add_argument('course_type')
            parser.add_argument('follower')
            parser.add_argument('learner')
            args = parser.parse_args()
            title = args.get('title')
            desc = args.get('desc')
            img_path = args.get('img_path')
            course_type = args.get('course_type')
            follower = args.get('follower')
            learner = args.get('learner')
            # 是否已有当前课程
            num = Course.query.filter_by(title=title).count()
            if num >= 1:
                msg = 'This type is exist!'
                logging.error('AddCourseType is error:{}'.format(msg))
                return {'message': msg, 'code': 500}
            course = Course(title=title, desc=desc, img_path=img_path, course_type=course_type, follower=follower,
                            learner=learner, user_id=user_id)
            db.session.add(course)
            db.session.commit()
            return marshal(course, course_fields)
        except:
            error = traceback.format_exc()
            logging.error('AddCourseType is error:{}'.format(error))
            return {'message': 'AddCourseType error', 'code': 500}


class AddChapters(Resource):
    """
    添加章节目录
    """

    @login_required
    def post(self):
        user_id = g.user_id
        user = UserBase.query.get(user_id)
        # 是否有添加的权限（默认超级管理员可以添加）
        if user.is_superuser != 2:
            msg = 'Not permission!'
            logging.error('AddCourseType is error:{}'.format(msg))
            return {'message': msg, 'code': 500}
        parser = reqparse.RequestParser()
        parser.add_argument('title', required=True)
        parser.add_argument('course_id', required=True)
        parser.add_argument('serial_num', default=1)
        args = parser.parse_args()
        title = args.get('title')
        course_id = args.get('course_id')
        serial_num = args.get('serial_num')
        # 判断当前course_id是否存在
        course = Course.query.get(course_id)
        if not course:
            return {'message': 'not find course', 'code': 407}
        chapters_num = Chapters.query.filter_by(title=title, course=course_id).count()
        if chapters_num >= 1:
            return {'message': '该文章已存在', 'code': 408}
        chapters = Chapters(title=title, course=course_id, serial_num=serial_num, user_id=user_id)
        db.session.add(chapters)
        db.session.commit()
        return marshal(chapters, chapters_fields)


class AddSections(Resource):
    """
    增加课程小节
    """

    @login_required
    def post(self):
        user_id = g.user_id
        user = UserBase.query.get(user_id)
        # 是否有添加的权限（默认超级管理员可以添加）
        if user.is_superuser != 2:
            msg = 'Not permission!'
            logging.error('AddSections is error:{}'.format(msg))
            return {'message': msg, 'code': 500}
        parser = reqparse.RequestParser()
        parser.add_argument('title', required=True)
        parser.add_argument('chapters_id', required=True)
        parser.add_argument('serial_num', default=1)
        parser.add_argument('learn_time', required=True)
        parser.add_argument('content', required=True)
        parser.add_argument('video', required=True)
        parser.add_argument('seq_num', required=True)
        args = parser.parse_args()
        title = args.get('title')
        chapters_id = args.get('chapters_id')
        serial_num = args.get('serial_num')
        learn_time = args.get('learn_time')
        content = args.get('content')
        video = args.get('video')
        seq_num = args.get('seq_num')

        if len(title) >= 24:
            return {'message': '标题长度太大', 'code': 408}
        chapters = Chapters.query.get(chapters_id)
        if not chapters:
            return {'message': '所属章节不存在', 'code': 409}

        section = Sections.query.filter_by(title=title, chapters=chapters_id).first()
        if section:
            return {'message': '当前小节已存在', 'code': 410}

        section = Sections(title=title, chapters=chapters_id, serial_num=serial_num, learn_time=learn_time,
                           content=content, video=video, seq_num=seq_num)
        db.session.add(section)
        db.session.commit()
        return {'message': 'ok', 'code': 200}


class GetCourse(Resource):
    """
    获取课程类别信息
    """

    def get(self):
        course = Course.query.all()
        return marshal(course, course_fields)


class UploadVideo(Resource):
    """
    上传视频
    """

    def post(self):
        try:
            f = request.files['file']
            # 注意：没有的文件夹一定要先创建，不然会提示没有该路径
            upload_path = os.path.join(UPLOAD_PATH, secure_filename(f.filename))
            f.save(upload_path)
            video_path = os.path.join('images', f.filename)
            url = 'http://127.0.0.1:8000/course/video/{}'.format(f.filename)
            return {'message': 'ok', 'code': 200, 'data': {'upload_path': url}}
        except:
            error = traceback.format_exc()
            logging.error('UploadVideo error:{}'.format(error))
            return {'message': error, 'code': 500}


class GetUploadFile(Resource):
    def get(self, filename):
        return send_from_directory(UPLOAD_PATH, filename)


class GetQiNiuYunToken(Resource):
    """
    获取七牛云的token
    """

    def get(self):
        token = get_upload_token()
        return {'token': token}, 200

class CourseSearch(Resource):
    """
    搜索课程
    """

    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument('q', required=True)
        args = parser.parse_args()
        search = args.get('q')
        es = ES(index_name='tb_course')
        result = es._search(search, fields=['title', 'desc'])
        # es.delete_index()
        # course_list = Course.query.whoosh_search(search, like=True, case_sensitive=True, limit=5,
        #                                          fields=['desc', 'title']).all()
        # return marshal(course_list, search_course_fields)
        return result


class AddTag(Resource):
    """
    添加标签
    """

    @login_required
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('title', required=True)
        args = parser.parse_args()
        title = args.get('title')
        tag = Tag(title=title)
        db.session.add(tag)
        db.session.commit()
        return {'message': 'ok'}


class TagSearch(Resource):
    """
    搜索标签
    """

    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument('search', required=True)
        args = parser.parse_args()
        search = args.get('search')

        # tag_list = Tag.query.whoosh_search(search).all()
        # return marshal(tag_list, tag_fields)

        es = ES(index_name='tb_course_tag')
        result = es.search(search, count=5)
        content = []
        if 'hits' in result:
            for data in result['hits']['hits']:
                print('222222222', data)
                content.append(data.get('_source'))
        return content


api.add_resource(AddCourseType, '/add_type', endpoint='course/add_type')
api.add_resource(AddCourse, '/add_course', endpoint='course/add_course')
api.add_resource(GetCourse, '/get_course', endpoint='course/get_course')
api.add_resource(AddChapters, '/add_chapter', endpoint='course/add_chapter')
api.add_resource(UploadVideo, '/upload_video', endpoint='upload_video')
api.add_resource(GetUploadFile, '/video/<filename>')
api.add_resource(GetQiNiuYunToken, '/get_upload_video_token', endpoint='get_upload_video_token')
api.add_resource(CourseSearch, '/search', endpoint='search')
api.add_resource(TagSearch, '/tag_search', endpoint='tag_search')
api.add_resource(AddTag, '/add_tag', endpoint='add_tag')
